# Import Markup for rendering safe HTML, and 'g' for Flask's application context globals.
from flask import Markup, g
# Import the base Model class from Flask-AppBuilder.
from flask_appbuilder import Model
# Import SQLAlchemy components for defining the model schema and constraints.
from sqlalchemy import Column, Integer, String, Text, UniqueConstraint

# Import the Flask application instance to access its configuration.
from myapp.app import app
# Import a custom base model that may contain shared logic or properties.
from myapp.models.base import MyappModelBase


# Get the metadata object from the base Model class. Metadata stores information about the database schema.
metadata = Model.metadata
# Get the application's configuration object.
conf = app.config


# Define the Dimension_table class, which maps to the 'dimension' table in the database.
# This model represents a dimension table, which is often used in data warehousing.
class Dimension_table(Model, MyappModelBase):
    # Specifies the name of the database table for this model.
    __tablename__ = 'dimension'
    # Defines table-level arguments, in this case, a unique constraint.
    # This ensures that the combination of 'sqllchemy_uri' and 'table_name' is unique across all rows.
    __table_args__ = (UniqueConstraint('sqllchemy_uri', 'table_name'),)
    # Defines the primary key column for the table.
    id = Column(Integer, primary_key=True)
    # Defines a column for the SQLAlchemy connection URI for the database where the table resides.
    sqllchemy_uri = Column(String(255), nullable=True)
    # Defines a column for the name of the dimension table.
    table_name = Column(String(255), nullable=True, unique=True)
    # Defines a column for a user-friendly label or display name for the table.
    label = Column(String(255), nullable=True)
    # Defines a column for a detailed description of the table.
    describe = Column(String(2000), nullable=True)
    # Defines a column to associate the dimension table with a specific application or product.
    app = Column(String(255), nullable=True)
    # Defines a column to list the owners or users responsible for this table, often as a comma-separated string.
    owner = Column(String(2000), nullable=True, default='')
    # Defines a column to store metadata about the table's columns, likely as a JSON string.
    columns = Column(Text, nullable=True, default='{}')
    # Defines a column for the status of the dimension table (e.g., 1 for active, 0 for inactive).
    status = Column(Integer, default=1)

    # This property generates an HTML representation of the table name.
    @property
    def table_html(self):
        """
        Generates an HTML link for the table name if the current user has permission.
        Otherwise, it returns the plain table name.
        Permissions are granted to admins, users listed in the 'owner' field, or if ownership is public ('*').
        """
        # Initialize an empty string for users.
        users = ''
        # Safely get the owner string.
        users = users + self.owner if self.owner else users
        # Split the comma-separated owner string into a list of usernames.
        users = users.split(',')
        # Clean up the list by stripping whitespace and removing empty entries.
        users = [user.strip() for user in users if user.strip()]
        # Get the base URL for the dimension model from the application's configuration.
        url_path = conf.get('MODEL_URLS', {}).get('dimension')
        # Check if the current logged-in user has access rights.
        if g.user.is_admin or g.user.username in users or '*' in self.owner:
            # If authorized, return the table name as a hyperlink to its detail page.
            return Markup(
                f'<a target=_blank href="{url_path}?targetId={self.id}">{self.table_name}</a>'
            )
        else:
            # If not authorized, return just the plain text table name.
            return self.table_name

    # This property generates HTML for action links related to the dimension table.
    @property
    def operate_html(self):
        """
        Generates a set of HTML links for operations that can be performed on this dimension table.
        """
        # Define a string template for the HTML links.
        url = (
            '<a target=_blank href="/dimension_table_modelview/api/create_external_table/%s">'
            '创建远程表</a>  | '
            '<a target=_blank href="/dimension_table_modelview/api/external/%s">'
            '建外表示例</a> | '
            '<a href="/dimension_table_modelview/api/clear/%s">清空表记录</a>'
        ) % (
            self.id,
            self.id,
            self.id,
        )
        # Wrap the generated HTML in Markup() to prevent it from being auto-escaped.
        return Markup(url)
